﻿#include "TlvTableWidget.h"
#include "IICTableWidget.h"
#include "components/IconButton/IconButton.h"
#include "services/tlv/Com/TlvThreadCom.h"
#include "utils/String/regexp.h"
#include "utils/String/hexbin.h"
#include "components/Toast/Toast.h"
#include "services/Task/TlvCmdTask.h"

#include <QHeaderView>
#include <QDebug>

#define COL_DESC 1
#define COL_TAG  2
#define COL_VAL  3
#define COL_WAIT 4

TlvTableWidget::TlvTableWidget(QWidget *parent)
    : CustomTableWidget(parent)
{
    // 设置表头
    QStringList headers;
    headers << tr("description") << tr("tag") << tr("value") << tr("wait(ms)") << tr("send");
    setHeaders(headers);

    // 设置列对齐方式
    setColumnAlignment(COL_DESC, Qt::AlignVCenter | Qt::AlignLeft);     // 描述列左对齐
    setColumnAlignment(COL_TAG , Qt::AlignVCenter | Qt::AlignHCenter);  // 标签列居中对齐
    setColumnAlignment(COL_VAL , Qt::AlignVCenter | Qt::AlignLeft);     // 数据列左对齐
    setColumnAlignment(COL_WAIT, Qt::AlignVCenter | Qt::AlignHCenter);  // 延时列居中对齐

    // 设置列宽和拉伸模式
    horizontalHeader()->setSectionResizeMode(COL_TAG, QHeaderView::Fixed);
    setColumnWidth(COL_TAG, 100);
    horizontalHeader()->setSectionResizeMode(COL_VAL, QHeaderView::Stretch);
    horizontalHeader()->setSectionResizeMode(COL_WAIT, QHeaderView::Fixed);
    setColumnWidth(COL_WAIT, 100);

    enableCellKeyEnterCallButton(true);

    connect(this, &TlvTableWidget::buttonClicked, this, &TlvTableWidget::sendTlv);
}

void TlvTableWidget::addTlvCmd(const QString &desc, const QString &tag, const QString &val, const QString &waitMs)
{
    insertTlvCmd(rowCount(), desc, tag, val, waitMs);
}

void TlvTableWidget::addTlvCmd(const QString &desc, uint16_t tag, const QByteArray &val, uint16_t waitMs)
{
    addTlvCmd(desc, QString::number(tag, 16).toUpper(), val.toHex(' ').toUpper(), QString::number(waitMs));
}

void TlvTableWidget::addTlvCmd(const QString &desc, const Tlv &tlv, const QString &waitMs)
{
    addTlvCmd(desc, tlv, waitMs.toUInt());
}

void TlvTableWidget::addTlvCmd(const QString &desc, const Tlv &tlv, uint16_t waitMs)
{
    addTlvCmd(desc, tlv.tag(), tlv.value(), waitMs);
}

void TlvTableWidget::addNewLine()
{
    addTlvCmd("", "", "");
}

void TlvTableWidget::insertNewLine(int row)
{
    insertTlvCmd(row, "", "", "");
}

void TlvTableWidget::enableTagAutoComplete(bool en)
{
    for (int i = 0; i < rowCount(); i++) {
        enableCellAutoComplete(i, COL_TAG, en);
    }
}

bool TlvTableWidget::getRowTlv(int row, Tlv *oTlv, uint16_t *oWaitMs)
{
    if (row < 0 || row >= rowCount()) return false;
    bool ok = true;
    if (oTlv) {
        uint16_t tag = cellText(row, COL_TAG).toUInt(&ok, 16);
        if (!ok) {
            Toast::warning(tr("[row %1] Tlv tag cannot be empty!").arg(row));
            return false;
        }
        QByteArray data = HexBin::parseHexString(cellText(row, COL_VAL), &ok);
        if (!ok || data.isEmpty()) {
            Toast::warning(tr("[row %1] Tlv value is invalid, please check it!").arg(row));
            return false;
        }
        *oTlv = Tlv(static_cast<TlvTag>(tag), data);
    }
    if (oWaitMs) {
        uint16_t waitMs = cellText(row, COL_WAIT).toUInt(&ok, 10);
        if (!ok) return false;
        *oWaitMs = waitMs;
    }
    return true;
}

QList<TlvCmdModel> TlvTableWidget::toTlvCmdModel()
{
    QList<TlvCmdModel> res;
    for (int i = 0; i < rowCount(); i++) {
        TlvCmdModel model;
        model.title = cellText(i, COL_DESC);
        model.value.tag = cellText(i, COL_TAG);
        model.value.hexstring = cellText(i, COL_VAL);
        model.wait = cellText(i, COL_WAIT);
        res.push_back(model);
    }
    return res;
}

void TlvTableWidget::sendTlv(int row)
{
    Tlv tlv = Tlv::tlvNull();
    if (!getRowTlv(row, &tlv, nullptr)) return;
    TlvThreadCom::instance()->write(tlv);
}

bool TlvTableWidget::sendSelected()
{
    QList<TlvSend_t> cmds;
    for (int i = 0; i < rowCount(); i++) {
        if (!isRowChecked(i)) continue;
        TlvSend_t cmd;
        if (!getRowTlv(i, &cmd.tlv, &cmd.wait)) {
            return false;
        }
        cmds.push_back(cmd);
    }
    TlvCmdTask::instance()->setRunTlvCmds(cmds);
    TlvCmdTask::instance()->start();
    return true;
}

void TlvTableWidget::insertTlvCmd(int row, const QString &desc, const QString &tag, const QString &val, const QString &waitMs)
{
    // 添加数据
    QStringList rowData;
    rowData << desc << tag << val << waitMs;

    IconButton* btnSend = new IconButton(this, QIcon(":/imgs/send.png"), "", IconButton::Small);
    insertRow(row, rowData, btnSend);

    int r = rowCount() - 1;
    setCellValidator(r, COL_TAG,  new QRegExpValidator(QRegExp(REGEXP_HEX_LL(4)), this));  // 标签
    setCellValidator(r, COL_VAL,  new QRegExpValidator(QRegExp(REGEXP_HEX_SP),    this));  // 数据
    setCellValidator(r, COL_WAIT, new QRegExpValidator(QRegExp(REGEXP_DEC_LL(4)), this));  // 延时

    setCellPasteCallback(r, COL_VAL, &IICTableWidget::onPasteHexCallback);

    // 自动补全下拉列表的显示内容和实际值
    QStringList displays, values;
    for (const TlvTag& tag: Tlv::allTags()) {
        const QString& numStr = QString("%1").arg(QString::number(tag, 16).toUpper(), 4, '0');
        displays << QString("%1 (%2)").arg(numStr, Tlv::tagStr(tag));
        values << numStr;
    }
    setCellAutoComplete(r, COL_TAG, displays, values);
}
